package com.cencat.order.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cencat.common.result.Result;
import com.cencat.order.dto.DriverDTO;
import com.cencat.order.service.DriverService;
import com.cencat.order.vo.DriverVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 司机控制器
 * 
 * @author cencat
 * @date 2024-01-20
 */
@Slf4j
@RestController
@RequestMapping("/api/driver")
@RequiredArgsConstructor
@Tag(name = "司机管理", description = "司机信息管理相关接口")
public class DriverController {

    private final DriverService driverService;

    @GetMapping("/page")
    @Operation(summary = "分页查询司机列表", description = "根据条件分页查询司机信息")
    public Result<IPage<DriverVO>> getDriverPage(
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") Long current,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Long size,
            @Parameter(description = "司机姓名") @RequestParam(required = false) String driverName,
            @Parameter(description = "司机编号") @RequestParam(required = false) String driverCode,
            @Parameter(description = "手机号码") @RequestParam(required = false) String phone,
            @Parameter(description = "司机状态") @RequestParam(required = false) Integer driverStatus,
            @Parameter(description = "在线状态") @RequestParam(required = false) Integer onlineStatus,
            @Parameter(description = "认证状态") @RequestParam(required = false) Integer verificationStatus,
            @Parameter(description = "车辆类型") @RequestParam(required = false) String vehicleType,
            @Parameter(description = "开始时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        
        log.info("分页查询司机列表，参数：current={}, size={}, driverName={}, driverCode={}, phone={}, driverStatus={}, onlineStatus={}, verificationStatus={}, vehicleType={}, startTime={}, endTime={}",
                current, size, driverName, driverCode, phone, driverStatus, onlineStatus, verificationStatus, vehicleType, startTime, endTime);
        
        Page<DriverVO> page = new Page<>(current, size);
        IPage<DriverVO> result = driverService.getDriverPage(page, driverName, driverCode, phone,
                driverStatus, onlineStatus, verificationStatus, vehicleType, startTime, endTime);
        
        return Result.success(result);
    }

    @GetMapping("/code/{driverCode}")
    @Operation(summary = "根据司机编号查询", description = "根据司机编号查询司机详细信息")
    public Result<DriverVO> getByDriverCode(
            @Parameter(description = "司机编号") @PathVariable String driverCode) {
        
        log.info("根据司机编号查询司机信息，driverCode={}", driverCode);
        
        DriverVO driver = driverService.getByDriverCode(driverCode);
        if (driver == null) {
            return Result.error("司机不存在");
        }
        
        return Result.success(driver);
    }

    @GetMapping("/phone/{phone}")
    @Operation(summary = "根据手机号查询", description = "根据手机号查询司机信息")
    public Result<DriverVO> getByPhone(
            @Parameter(description = "手机号码") @PathVariable String phone) {
        
        log.info("根据手机号查询司机信息，phone={}", phone);
        
        DriverVO driver = driverService.getByPhone(phone);
        if (driver == null) {
            return Result.error("司机不存在");
        }
        
        return Result.success(driver);
    }

    @GetMapping("/status")
    @Operation(summary = "根据状态查询司机", description = "根据司机状态、在线状态等查询司机列表")
    public Result<List<DriverVO>> getByStatus(
            @Parameter(description = "司机状态") @RequestParam(required = false) Integer driverStatus,
            @Parameter(description = "在线状态") @RequestParam(required = false) Integer onlineStatus,
            @Parameter(description = "认证状态") @RequestParam(required = false) Integer verificationStatus,
            @Parameter(description = "开始时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "100") Integer limit) {
        
        log.info("根据状态查询司机列表，driverStatus={}, onlineStatus={}, verificationStatus={}, startTime={}, endTime={}, limit={}",
                driverStatus, onlineStatus, verificationStatus, startTime, endTime, limit);
        
        List<DriverVO> drivers = driverService.getByStatus(driverStatus, onlineStatus, verificationStatus,
                startTime, endTime, limit);
        
        return Result.success(drivers);
    }

    @GetMapping("/location")
    @Operation(summary = "根据位置查询司机", description = "根据经纬度和半径查询附近的司机")
    public Result<List<DriverVO>> getByLocation(
            @Parameter(description = "经度") @RequestParam BigDecimal longitude,
            @Parameter(description = "纬度") @RequestParam BigDecimal latitude,
            @Parameter(description = "半径(公里)") @RequestParam BigDecimal radius,
            @Parameter(description = "司机状态") @RequestParam(required = false) Integer driverStatus,
            @Parameter(description = "在线状态") @RequestParam(required = false) Integer onlineStatus,
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "50") Integer limit) {
        
        log.info("根据位置查询司机列表，longitude={}, latitude={}, radius={}, driverStatus={}, onlineStatus={}, limit={}",
                longitude, latitude, radius, driverStatus, onlineStatus, limit);
        
        List<DriverVO> drivers = driverService.getByLocation(longitude, latitude, radius,
                driverStatus, onlineStatus, limit);
        
        return Result.success(drivers);
    }

    @GetMapping("/vehicle-type/{vehicleType}")
    @Operation(summary = "根据车辆类型查询司机", description = "根据车辆类型查询司机列表")
    public Result<List<DriverVO>> getByVehicleType(
            @Parameter(description = "车辆类型") @PathVariable String vehicleType,
            @Parameter(description = "司机状态") @RequestParam(required = false) Integer driverStatus,
            @Parameter(description = "在线状态") @RequestParam(required = false) Integer onlineStatus,
            @Parameter(description = "开始时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "100") Integer limit) {
        
        log.info("根据车辆类型查询司机列表，vehicleType={}, driverStatus={}, onlineStatus={}, startTime={}, endTime={}, limit={}",
                vehicleType, driverStatus, onlineStatus, startTime, endTime, limit);
        
        List<DriverVO> drivers = driverService.getByVehicleType(vehicleType, driverStatus, onlineStatus,
                startTime, endTime, limit);
        
        return Result.success(drivers);
    }

    @GetMapping("/statistics")
    @Operation(summary = "司机统计信息", description = "获取司机相关统计数据")
    public Result<Map<String, Object>> getDriverStatistics(
            @Parameter(description = "司机状态") @RequestParam(required = false) Integer driverStatus,
            @Parameter(description = "在线状态") @RequestParam(required = false) Integer onlineStatus,
            @Parameter(description = "认证状态") @RequestParam(required = false) Integer verificationStatus,
            @Parameter(description = "车辆类型") @RequestParam(required = false) String vehicleType,
            @Parameter(description = "开始时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        
        log.info("查询司机统计信息，driverStatus={}, onlineStatus={}, verificationStatus={}, vehicleType={}, startTime={}, endTime={}",
                driverStatus, onlineStatus, verificationStatus, vehicleType, startTime, endTime);
        
        Map<String, Object> statistics = driverService.getDriverStatistics(driverStatus, onlineStatus,
                verificationStatus, vehicleType, startTime, endTime);
        
        return Result.success(statistics);
    }

    @PostMapping
    @Operation(summary = "创建司机", description = "创建新的司机信息")
    public Result<Boolean> createDriver(@Valid @RequestBody DriverDTO driverDTO) {
        log.info("创建司机，driverDTO={}", driverDTO);
        
        boolean result = driverService.createDriver(driverDTO);
        if (result) {
            return Result.success(true, "司机创建成功");
        } else {
            return Result.error("司机创建失败");
        }
    }

    @PutMapping("/{driverId}")
    @Operation(summary = "更新司机信息", description = "更新指定司机的信息")
    public Result<Boolean> updateDriver(
            @Parameter(description = "司机ID") @PathVariable Long driverId,
            @Valid @RequestBody DriverDTO driverDTO) {
        
        log.info("更新司机信息，driverId={}, driverDTO={}", driverId, driverDTO);
        
        boolean result = driverService.updateDriver(driverId, driverDTO);
        if (result) {
            return Result.success(true, "司机信息更新成功");
        } else {
            return Result.error("司机信息更新失败");
        }
    }

    @PutMapping("/{driverId}/location")
    @Operation(summary = "更新司机位置", description = "更新司机的实时位置信息")
    public Result<Boolean> updateDriverLocation(
            @Parameter(description = "司机ID") @PathVariable Long driverId,
            @Parameter(description = "经度") @RequestParam BigDecimal longitude,
            @Parameter(description = "纬度") @RequestParam BigDecimal latitude,
            @Parameter(description = "位置地址") @RequestParam(required = false) String locationAddress,
            @Parameter(description = "位置时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime locationTime) {
        
        log.info("更新司机位置，driverId={}, longitude={}, latitude={}, locationAddress={}, locationTime={}",
                driverId, longitude, latitude, locationAddress, locationTime);
        
        boolean result = driverService.updateDriverLocation(driverId, longitude, latitude,
                locationAddress, locationTime);
        if (result) {
            return Result.success(true, "司机位置更新成功");
        } else {
            return Result.error("司机位置更新失败");
        }
    }

    @PutMapping("/{driverId}/status")
    @Operation(summary = "更新司机状态", description = "更新司机的工作状态")
    public Result<Boolean> updateDriverStatus(
            @Parameter(description = "司机ID") @PathVariable Long driverId,
            @Parameter(description = "司机状态") @RequestParam Integer driverStatus,
            @Parameter(description = "状态备注") @RequestParam(required = false) String statusRemark) {
        
        log.info("更新司机状态，driverId={}, driverStatus={}, statusRemark={}",
                driverId, driverStatus, statusRemark);
        
        boolean result = driverService.updateDriverStatus(driverId, driverStatus, statusRemark);
        if (result) {
            return Result.success(true, "司机状态更新成功");
        } else {
            return Result.error("司机状态更新失败");
        }
    }

    @PutMapping("/{driverId}/online-status")
    @Operation(summary = "更新在线状态", description = "更新司机的在线状态")
    public Result<Boolean> updateOnlineStatus(
            @Parameter(description = "司机ID") @PathVariable Long driverId,
            @Parameter(description = "在线状态") @RequestParam Integer onlineStatus,
            @Parameter(description = "状态备注") @RequestParam(required = false) String statusRemark) {
        
        log.info("更新司机在线状态，driverId={}, onlineStatus={}, statusRemark={}",
                driverId, onlineStatus, statusRemark);
        
        boolean result = driverService.updateOnlineStatus(driverId, onlineStatus, statusRemark);
        if (result) {
            return Result.success(true, "在线状态更新成功");
        } else {
            return Result.error("在线状态更新失败");
        }
    }

    @PutMapping("/{driverId}/verification")
    @Operation(summary = "更新认证状态", description = "更新司机的认证状态")
    public Result<Boolean> updateVerificationStatus(
            @Parameter(description = "司机ID") @PathVariable Long driverId,
            @Parameter(description = "认证状态") @RequestParam Integer verificationStatus,
            @Parameter(description = "认证备注") @RequestParam(required = false) String verificationRemark,
            @Parameter(description = "认证时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime verificationTime,
            @Parameter(description = "认证人员ID") @RequestParam(required = false) Long verifierId) {
        
        log.info("更新司机认证状态，driverId={}, verificationStatus={}, verificationRemark={}, verificationTime={}, verifierId={}",
                driverId, verificationStatus, verificationRemark, verificationTime, verifierId);
        
        boolean result = driverService.updateVerificationStatus(driverId, verificationStatus,
                verificationRemark, verificationTime, verifierId);
        if (result) {
            return Result.success(true, "认证状态更新成功");
        } else {
            return Result.error("认证状态更新失败");
        }
    }

    @PutMapping("/batch/status")
    @Operation(summary = "批量更新司机状态", description = "批量更新多个司机的状态")
    public Result<Boolean> batchUpdateDriverStatus(
            @Parameter(description = "司机ID列表") @RequestParam List<Long> driverIds,
            @Parameter(description = "司机状态") @RequestParam Integer driverStatus) {
        
        log.info("批量更新司机状态，driverIds={}, driverStatus={}", driverIds, driverStatus);
        
        boolean result = driverService.batchUpdateDriverStatus(driverIds, driverStatus);
        if (result) {
            return Result.success(true, "批量更新司机状态成功");
        } else {
            return Result.error("批量更新司机状态失败");
        }
    }

    @DeleteMapping("/{driverId}")
    @Operation(summary = "删除司机", description = "软删除指定的司机信息")
    public Result<Boolean> softDeleteDriver(
            @Parameter(description = "司机ID") @PathVariable Long driverId) {
        
        log.info("软删除司机，driverId={}", driverId);
        
        boolean result = driverService.softDeleteDriver(driverId);
        if (result) {
            return Result.success(true, "司机删除成功");
        } else {
            return Result.error("司机删除失败");
        }
    }

    @DeleteMapping("/batch")
    @Operation(summary = "批量删除司机", description = "批量软删除多个司机信息")
    public Result<Boolean> batchSoftDeleteDrivers(
            @Parameter(description = "司机ID列表") @RequestParam List<Long> driverIds) {
        
        log.info("批量软删除司机，driverIds={}", driverIds);
        
        boolean result = driverService.batchSoftDeleteDrivers(driverIds);
        if (result) {
            return Result.success(true, "批量删除司机成功");
        } else {
            return Result.error("批量删除司机失败");
        }
    }

    @PutMapping("/{driverId}/restore")
    @Operation(summary = "恢复司机", description = "恢复已删除的司机信息")
    public Result<Boolean> restoreDriver(
            @Parameter(description = "司机ID") @PathVariable Long driverId) {
        
        log.info("恢复已删除的司机，driverId={}", driverId);
        
        boolean result = driverService.restoreDriver(driverId);
        if (result) {
            return Result.success(true, "司机恢复成功");
        } else {
            return Result.error("司机恢复失败");
        }
    }

    @GetMapping("/{driverId}/login-logs")
    @Operation(summary = "查询登录日志", description = "查询司机的登录日志记录")
    public Result<List<Map<String, Object>>> getDriverLoginLogs(
            @Parameter(description = "司机ID") @PathVariable Long driverId,
            @Parameter(description = "开始时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "100") Integer limit) {
        
        log.info("查询司机登录日志，driverId={}, startTime={}, endTime={}, limit={}",
                driverId, startTime, endTime, limit);
        
        List<Map<String, Object>> logs = driverService.getDriverLoginLogs(driverId, startTime, endTime, limit);
        
        return Result.success(logs);
    }
}